﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Gencode.PrsUtil.Controls;
using System.Data;

namespace Personalplaner.Modules.Dienstplan.Print
{
	public class GridPrintDocument : IGridPrintDocument
	{
		enum PrintLevel { PRINT_INIT, GRIDS_CREATED, GRIDS_RENDERED, GRID_ERROR };

		Modules.Dienstplan.Print.GridPrintPreview PrintGrid;

		IGridParameters parameters;

		PrintLevel printLevel = PrintLevel.PRINT_INIT;

		/// <summary>
		/// Abteilung to be printed, 0 if all should be printed
		/// </summary>
		public int AbteilungID
		{
			get
			{
				return parameters.AbteilungID;
			}
			set
			{
				parameters.AbteilungID = value;
			}
		}

		public DataGridView MainGrid
		{
			get
			{
				return parameters.MainGrid;
			}
			set
			{
				parameters.MainGrid = value;
			}
		}

		public DataGridView TimeGrid
		{
			get
			{
				return parameters.TimeGrid;
			}
			set
			{
				parameters.TimeGrid = value;
			}
		}

		List<int> abteilungRows;
		public List<int> AbteilungRows
		{
			get
			{
				return abteilungRows;
			}
			set
			{
				abteilungRows = value;
			}
		}

		public Gencode.PrsCommon.Data.Plan.Grid GridData
		{
			get
			{
				return parameters.GridData;
			}
			set
			{
				parameters.GridData = value;
			}
		}

		public int PageSize
		{
			get
			{
				return parameters.PageSize;
			}
			set
			{
				parameters.PageSize = value;
			}
		}

		public DataGridView Grid
		{
			get
			{
				return PrintGrid.Grid;
			}
		}

		public List<DataGridView> Grids
		{
			get
			{
				return PrintGrid.Grids;
			}
		}

		public bool CloseAfterCreate
		{
			get
			{
                if (PrintGrid != null)
				return PrintGrid.CloseAfterCreate;
                return false;
			}
			set
			{
                if(PrintGrid!=null)
				PrintGrid.CloseAfterCreate = value;
			}
		}

		public int GridHeight
		{
			get;
			set;
		}

		public GridPrintDocument(IGridParameters gridParameters)
		{
			this.parameters = gridParameters;
		}

		public void PrintGrids()
		{
			PrintGrid = new Personalplaner.Modules.Dienstplan.Print.GridPrintPreview();
			PrintGrid.GridDocument = this;
            if (!parameters.Preview)
                CloseAfterCreate = true;
            else
                CloseAfterCreate = false;

			printLevel = PrintLevel.PRINT_INIT;
			if (MainGrid == null || TimeGrid == null || GridData == null)
			{
				printLevel = PrintLevel.GRID_ERROR;
				Gencode.Common.ActionLogger.Logger.LoggMessage(Gencode.Common.ActionLogger.MessageType.DATA_ERROR,
					"Grid null reference while printing");
				Gencode.Common.Util.ErrorHandler.LoggError("Grid null-reference", "GridPrintDocument.PrintGrids", "A grid (MainGrid,TimeGrid,GridData) returned a null reference.\nCheck if grids are referenced corectly");
				Gencode.Common.Util.ErrorHandler.ShowError("Es ist ein Fehler beim Erstellen des Druckauftrags aufgetreten.", "Druckfehler");

				return;
			}
			PrintGrid.ShowDialog();
		}

		/// <summary>
		/// Will create all grids for printing.
		/// Is called automatically by PrintGrids()
		/// </summary>
		public void CreateGridsForPrint()
		{
			if (printLevel == PrintLevel.PRINT_INIT)
			{
				//Set amount of grids
				//if grid is bigger than 1 page then draw each abteilung in a separate grid
				GridHeight = 0;
				if (MainGrid.Rows.Count >= 2)
					GridHeight = (MainGrid.Rows.Count * MainGrid.Rows[1].Height) + 104;



                //if (GridHeight > PageSize)
                //{
					abteilungRows = new List<int>();
					int i = 0;
					int curAbt = GridData[i].AbteilungID;
					int prevAbt = curAbt;

					PrintGrid.PrinteableGrids.Add(new PrinteableGrid());

					while (i /*+ GridData.PreColumnCount <= MainGrid.Rows.Count*/< GridData.Rows.Length)
					{
						prevAbt = curAbt;
						curAbt = GridData[i].AbteilungID;

						if (prevAbt != curAbt)
						{
							abteilungRows.Add(i/* + GridData.PreColumnCount - 1*/);
							PrintGrid.PrinteableGrids.Add(new PrinteableGrid());
						}
						i++;
					}
                //}
                //else
                //    PrintGrid.PrinteableGrids.Add(new PrinteableGrid());

				printLevel = PrintLevel.GRIDS_CREATED;
			}
		}

		/// <summary>
		/// Renders the grids in a dialog
		/// Is called automatically by PrintGrids()
		/// </summary>
		public void RenderGrid()
		{
			if (printLevel == PrintLevel.GRIDS_CREATED)
			{
				int startIndex = 0;
				int endIndex = 1;
				if (PrintGrid.GridIndex < abteilungRows.Count)
					endIndex = abteilungRows[PrintGrid.GridIndex];
				else
					endIndex = abteilungRows.Count;
				while (PrintGrid.GridIndex <= abteilungRows.Count && startIndex != endIndex)
				{
					DataTable dt = new DataTable("1");

					//Create Columns of new DataTable
					for (int i = 0; i < MainGrid.Columns.Count; i++)
					{
						dt.Columns.Add(MainGrid.Columns[i].HeaderText);
					}

					//Create Rows of new DataTable
					for (int i = startIndex; i < endIndex; i++)
					{
						DataRow dr = dt.NewRow();
						dr[0] = "";
						dt.Rows.Add(dr);
					}

					PrintGrid.PrinteableGrids[PrintGrid.GridIndex].DataSource = dt;

					//add Saldos
					if (PlanOption.PrintSoll == 1)
					{
						dt.Columns.Add("Soll");
						for (int i = startIndex; i < endIndex; i++)
						{
							double rnd;
							string value = "";

							if (TimeGrid[1, i].Value != null)
							{
								if (TimeGrid[1, i].Value.ToString() != String.Empty)
								{
									rnd = (double)(int)(100 * (double.Parse(TimeGrid[1, i].Value.ToString())));
									value = "" + (rnd / 100);
								}
							}
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Value = value;

							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Style.BackColor = TimeGrid[1, i].Style.BackColor;
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Style.Alignment = (DataGridViewContentAlignment)TimeGrid.Columns[1].DefaultCellStyle.Alignment;
						}
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1].HeaderCell.Style = TimeGrid.Columns[1].HeaderCell.Style;
					}

					if (PlanOption.PrintHaben == 1)
					{
						dt.Columns.Add("Haben");
						for (int i = startIndex; i < endIndex; i++)
						{
							double rnd;
							string value = "";

							if (TimeGrid[2, i].Value != null)
							{
								if (TimeGrid[1, i].Value.ToString() != String.Empty)
								{
									rnd = (double)(int)(100 * (double.Parse(TimeGrid[2, i].Value.ToString())));
									value = "" + (rnd / 100);
								}
							}

							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Value = value;

							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Style.BackColor = TimeGrid[2, i].Style.BackColor;
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Style.Alignment = (DataGridViewContentAlignment)TimeGrid.Columns[2].DefaultCellStyle.Alignment;
						}
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1].HeaderCell.Style = TimeGrid.Columns[2].HeaderCell.Style;
					}

					if (PlanOption.PrintSaldoDiff == 1)
					{
						dt.Columns.Add("Diff");
						for (int i = startIndex; i < endIndex; i++)
						{
							double rnd;
							string value = "";

							if (TimeGrid[3, i].Value != null)
							{
								if (TimeGrid[2, i].Value.ToString() != String.Empty)
								{
									try
									{
										rnd = (double)(int)(100 * double.Parse(TimeGrid[4, i].Value.ToString()));
										value = "" + (rnd / 100);
									}
									catch
									{
										value = TimeGrid[4, i].Value.ToString();
									}
								}
							}

							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Value = value;

							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Style.BackColor = TimeGrid[4, i].Style.BackColor;
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1, i - startIndex].Style.Alignment = (DataGridViewContentAlignment)TimeGrid.Columns[4].DefaultCellStyle.Alignment;
						}
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns.Count - 1].HeaderCell.Style = TimeGrid.Columns[4].HeaderCell.Style;
					}

					//set height of cells
					for (int r = startIndex; r < endIndex; r++)
					{
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Rows[r - startIndex].Height = MainGrid.Rows[r].Height;
					}

					//Copy all Data from mainGrid
					for (int c = 0; c < MainGrid.Columns.Count; c++)
					{
                        //TODO:
                        //these 2 loops have a high cost!
                        //try to make code faster!!
						for (int r = startIndex; r < endIndex; r++)
						{
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[c, r - startIndex].Value = MainGrid[c, r].Value;
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[c, r - startIndex].Style.BackColor = MainGrid[c, r].Style.BackColor;
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[c, r - startIndex].Style.ForeColor = MainGrid[c, r].Style.ForeColor;
							PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid[c, r - startIndex].Style.Alignment = (DataGridViewContentAlignment)MainGrid.Columns[c].DefaultCellStyle.Alignment;
						}
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[c].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
						PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns[c].HeaderCell.Style = MainGrid.Columns[c].HeaderCell.Style;
					}

					foreach (DataGridViewColumn column in PrintGrid.PrinteableGrids[PrintGrid.GridIndex].Grid.Columns)
					{
						column.SortMode = DataGridViewColumnSortMode.NotSortable;
					}

					if (PrintGrid.GridIndex < abteilungRows.Count)
						startIndex = abteilungRows[PrintGrid.GridIndex];

					PrintGrid.GridIndex++;

					if (PrintGrid.GridIndex < abteilungRows.Count)
						endIndex = abteilungRows[PrintGrid.GridIndex];
					else
						endIndex = MainGrid.Rows.Count;
				}
				printLevel = PrintLevel.GRIDS_RENDERED;
			}
		}
	}
}
